Skip to content

KCL executor: Iterate over binary ops (instead of recursing)#6226

Closed
adamchalmers wants to merge 1 commit intomainfrom
achalmers/iterative-binary-ops
Closed

KCL executor: Iterate over binary ops (instead of recursing)#6226
adamchalmers wants to merge 1 commit intomainfrom
achalmers/iterative-binary-ops

Conversation

@adamchalmers
Copy link
Contributor

@adamchalmers adamchalmers commented Apr 8, 2025

Doesn't actually have any performance impact. But it does avoid the stack overflow we were running into.

Restores this add_lots stress test to its glorious full size, undoing the temporary fix of ce7a967 (#6174)

This probably has a bug around operator precedence. Hopefully CI lets me know.

@qa-wolf
Copy link

qa-wolf bot commented Apr 8, 2025

QA Wolf here! As you write new code it's important that your test coverage is keeping up.
Click here to request test coverage for this PR!

@vercel
Copy link

vercel bot commented Apr 8, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated (UTC)
modeling-app ✅ Ready (Inspect) Visit Preview Apr 8, 2025 10:32pm

@adamchalmers adamchalmers changed the title Iterate over binary ops (instead of recursing) KCL executor: Iterate over binary ops (instead of recursing) Apr 8, 2025
@adamchalmers adamchalmers force-pushed the achalmers/iterative-binary-ops branch from e1ca04d to 7711bf7 Compare April 8, 2025 22:15
@adamchalmers adamchalmers marked this pull request as ready for review April 8, 2025 22:18
@adamchalmers adamchalmers requested review from jessfraz, jtran and nrc April 8, 2025 22:20
let metadata = partial.metadata();
partial = do_binary_op(
partial,
next_binary_expr.right.get_result(exec_state, ctx).await?,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and above we're still recursing down the right hand side.

I'm not sure about precedence, that shouldn't be an issue because it should be unambiguous after parsing, but I'm not exactly clear about the order of operations here. Because KCL is mostly immutable, I don't think evaluation order is important, though I would rather it were preserved with this refactoring just in case there is an interesting edge case with tags or something.

I would expect to implement this with basically a manual stack - using a Vec rather than the Rust stack for the KCL call stack. Then it's just an iterative depth-first traversal of the AST and we maintain evaluation order

@jessfraz
Copy link
Contributor

NICE!

adamchalmers added a commit that referenced this pull request Jun 5, 2025
Previously in a member expression like `foo.x` or `foo[3]`, `foo` had to be an identifier. You could not do something like `f().x` (and if you tried, you got a cryptic error). Rather than make the error better, we should just accept any expression to be the LHS of a member expression (aka its 'object').

This does knock our "parse lots of function calls" from 58 to 55 calls before it stack overflows. But I think it's fine, we'll address this in #6226 when I get back to it.

Closes #7273
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants